
#include "epollLoop.hpp"
#include <iostream>
EpollLoop::~EpollLoop()
{
    close(epfd);
    m_Connects.clear();
}

void EpollLoop::addConnect(int fd, uint32_t events)
{
    struct epoll_event ev;
    ev.events = events;
    auto con = std::make_unique<Connectfd>(fd, this, Connectfd::State::ACCEPTING);
    ev.data.ptr = con.get();
    m_Connects[fd] = std::move(con);
    epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
}

void EpollLoop::addConnectClient(int fd, uint32_t events)
{
    struct epoll_event ev;
    ev.events = events;
    auto con = std::make_unique<Connectfd>(fd, this);
    ev.data.ptr = con.get();
    m_Connects[fd] = std::move(con);
    epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
}

void EpollLoop::removeConn(int fd)
{
    std::cout << "removeConn fd:" << fd << std::endl;
    close(fd);
    epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
    m_Connects.erase(fd);
}

void EpollLoop::modefiyEvent(int fd, uint32_t events)
{
    epoll_event ev;
    ev.events = events;
    ev.data.ptr = m_Connects[fd].get();
    epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);
}

void EpollLoop::run()
{
    struct epoll_event events[MAX_EVENT];
    while (true)
    {
        // std::cout << "epoll_wait" << std::endl;
        int nready = epoll_wait(epfd, events, MAX_EVENT - 1, -1);
        for (int i = 0; i < nready; i++)
        {
            // std::cout << "epoll_wait start....." << std::endl;
            Connectfd *conn = static_cast<Connectfd *>(events[i].data.ptr);
            conn->handelEvent(events[i].events);
            if (conn->state() == Connectfd::State::CLOSE)
            {
                removeConn(conn->fdVal());
            }
            else if (conn->state() == Connectfd::State::WRITEING)
            {
                modefiyEvent(conn->fdVal(), EPOLLOUT);
            }
            else
            {
                modefiyEvent(conn->fdVal(), EPOLLIN);
            }
        }
    }
}
